import axios from 'axios';
import { message } from 'ant-design-vue';
import { useUserStore } from '@/store';

// const store = useUserStore() 这个store初始化的值不能放在这里，ts文件执行的时机太早了，
// 问自己问题：
// 拦截器分几种？
// 请求基地址 怎么分 开发环境和生产环境--- .env
// 请求拦截器里面一般干啥？
// 响应拦截器一般做什么操作？---- 响应成功的函数，什么时候执行，响应失败的函数什么时候执行？
const request = axios.create({
  // baseURL: process.env.VUE_APP_BASE_API,
  baseURL: 'https://api-hmzs.itheima.net/api',
  // baseURL: '/api', // 将api文件夹里面的请求 地址 用 /api拼接一下
  //  // 请求的超时时间，有些请求比如数据量比较大，那么需要的时间比较长比如需要6s才能返回
  // 请求超时报的错误 有个单词  timeout
  timeout: 10000,
});

// 写两个拦截器
// 请求拦截器 --- 一般在请求拦截器里面 给所有请求添加一个token，属性一般是Authorization
request.interceptors.request.use(
  (config) => {
    const store = useUserStore();
    const token = store.token;
    if (token) {
      // 如果cookie里面有token，就给所有的请求头 添加一个token值，属性名称 去接口文档里面找
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器：一般做 1.数据脱壳处理，2.业务成功业务失败，3.401token失效的处理
request.interceptors.response.use(
  // 第一个函数都属于请求成功，但是业务有成功和失败， 状态码是2xx 3xx
  (res) => {
    // 下面判断用户请求的业务成功，要后端java他们告诉我们
    if (res.data?.code === 10000) {
      // 脱壳
      return res.data;
    } else {
      message.error(res.data?.message || '请求失败');

      // 业务失败
      //提示个错误
      return Promise.reject(res);
    }
  },
  (err) => {
    if (err.response?.data?.msg) {
      message.error(err.response?.data?.msg);
    }
    // console.log('请求失败4xx 或者5xx会执行这里:', err);

    // 下面这里的函数是请求失败，http状态码是 4xx 5xx
    // TODO 5. 处理401错误
    if (err.response?.status === 401) {
      // 进入了这里表示token 失效了，应该退出到登录界面，并且将token还有本地储存等数据清空
      // const store = userStore()
      // store.delUser()
      // router.push('/login')
      return Promise.reject(err);
    }
    // 不是401就给个错误提示，在返回失败的promise
    return Promise.reject(err);
  }
);

export const myrequest = (url: string, method: string, obj?: any) => {
  if (!obj) {
    return request.request({
      url,
      method,
    });
  }
  return request.request({
    url,
    method,
    // 动态的key，使用数组的中括号形式去写
    [method.toUpperCase() === 'GET' ? 'params' : 'data']: obj,
    // data: obj,
    // params: obj
  });
};
